package se.webbzon.boltzmann.menu;

import java.awt.image.ImageObserver;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import se.webbzon.oschi01.worldcamera.WorldCameraPane;

public abstract class MFlowPage extends MPage {
	
	// The layout of this menu flow page
	private final FlowPageLayout layout;
	
	// A sorted list of all the items in this menu flow page
	// as they were added to the page
	private final List<MItem> items;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public MFlowPage(ImageObserver observer, FlowPageLayout layout, String name) {
		this(observer,layout,null,name);
	}

	public MFlowPage(ImageObserver observer, FlowPageLayout layout, MPage parent, String name) {
		super(observer, parent, name);
		this.layout = layout;
		items = Collections.synchronizedList(new ArrayList<MItem>());
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the layout of this game menu page. **/
	public FlowPageLayout getLayout() {
		return layout;
	}
	
	/** Adds a new empty row for the upcoming game menu items. **/
	public void addRow() {
		addRow(1);
	}
	
	/** Adds a new empty row for the upcoming game menu items. The vertical 
	 * space between the old and the new row will be given by the layout
	 * and the relative factor "spacing". Normal spacing is acquired when
	 * spacing = 1.0.  **/
	public void addRow(double spacing) {
		addItem(new MRow(spacing));
	}
	
	@Override public boolean addItem(MItem item) {
		if (super.addItem(item)) {
			items.add(item);
			return true;
		} else
			return false;
	}
	
	@Override public boolean removeItem(MItem item) {
		if (super.removeItem(item)) {
			items.remove(item);
			return true;
		} else
			return false;
	}

	@Override public void removeAll() {
		super.removeAll();
		items.clear();
	}
	
	@Override public void onRedoLayout() {
		int x = layout.getXOffset();
		int y = layout.getYOffset();
		int maxHeight = 0;
		synchronized (items) {
			for (MItem item : items) {
				item.setX(x);
				item.setY(y);
				if (item instanceof MRow) {
					y += maxHeight + ((MRow) item).getHeight();
					x = layout.getXOffset();
					maxHeight = 0;
				} else {
					maxHeight = Math.max(maxHeight, item.getHeight());
					x += item.getWidth() + layout.getXSpacing();
				}
			}
		}
	}

	
	/*============================================================
	Private Classes
	============================================================*/

	/** A row menu item used to indicate the use of a new row in the flow layout. **/
	private final class MRow extends MItem {
		
		public MRow(double spacing) {
			super(0,0,0,0,(int) (layout.getYSpacing() * spacing));
		}

		@Override public void onDraw(GameMenu menu, WorldCameraPane hud) {};

		@Override public void onPress(GameMenu menu, int x, int y) {};

		@Override public void onRelease(GameMenu menu, int x, int y) {};

		@Override public boolean isDraggable() {
			return false;
		}

		@Override public boolean isFocusable() {
			return false;
		}
		
	}

}
